#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import os
import webapp2
import jinja2
import re
import Cookies
import Users
from google.appengine.ext import db

template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir), autoescape=True)

class RootHandler(webapp2.RequestHandler):
    def get(self):
        self.redirect('/nerdpress')

class Handler(webapp2.RequestHandler):
    def write(self, *a, **kw):
        self.response.out.write(*a, **kw)
    def render_str(self, template, **params):
        t = jinja_env.get_template(template)
        return t.render(params)
    def render(self, template, **kw):
        self.write(self.render_str(template, **kw))
    def get_secure_cookie(self, cookie_str):
        return Cookies.check_secure_val(self.request.cookies.get(cookie_str))
    def set_secure_cookie(self, name, val):
        self.response.headers.add_header('Set-Cookie', '%s=%s; Path=/' % (name, str(Cookies.make_secure_val(val))))

class BlogHandler(Handler):
    def render_blog(self):
        uname = self.get_secure_cookie('name')
        entries = db.GqlQuery("SELECT * FROM BlogEntry ORDER BY created DESC LIMIT 10")
        self.render("BlogFront.html", entries=entries, name=uname)

    def get(self):
        self.render_blog()

class NewPostHandler(Handler):
    def render_new_post(self, error="", subject="", content=""):
        self.render("NewPostForm.html", error=error, subject=subject, content=content)

    def get(self):
        self.render("NewPostForm.html")

    def post(self):
        subject = self.request.get("subject")
        content = self.request.get("content")
        if subject and content:
            a = BlogEntry(subject=subject, content=content)
            a.put()
            self.redirect('/nerdpress/perm?p=' + str(a.key().id()))
        else:
            error = "Please add a title and content"
            self.render_new_post(error, subject, content)

class PermalinkHandler(Handler):
    def render_permalink(self, entry=""):
        self.render("Permalink.html", entry=entry)

    def get(self):
        entryKey = self.request.get("p")
        entry = BlogEntry.get_by_id(int(entryKey))
        self.render_permalink(entry)

class BlogEntry(db.Model):
    subject = db.StringProperty(required=True)
    content = db.TextProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)

#
# Signup/registration code:
#
USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
def valid_username(username):
    return USER_RE.match(username)

PASS_RE = re.compile(r"^.{3,20}$")
def valid_password(password):
    return PASS_RE.match(password)

EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")
def valid_email(email):
    return EMAIL_RE.match(email)

class SignupHanlder(Handler):
    def get(self):
        self.render("signup-form.html")

    def post(self):
        have_error = False
        in_user = self.request.get('username')
        in_email = self.request.get('email')
        in_pwd = self.request.get('password')
        in_ver = self.request.get('verify')

        params = dict(s_un=in_user, s_em=in_email)

        if not valid_username(in_user):
            have_error = True
            params['user_error'] = 'That\'s not a valid username.'
        elif not Users.available_username(in_user):
            have_error = True
            params['user_error'] = 'That user name is not available.'

        if not valid_password(in_pwd):
            have_error = True
            params['pass_error'] = 'That wasn\'t a valid password.'
        elif in_pwd != in_ver:
            have_error = True
            params['verify_error'] = 'Your passwords didn\'t match.'

        if in_email and not valid_email(in_email):
            have_error = True
            params['email_error'] = 'That\'s not a valid email.'

        if have_error:
            self.render('signup-form.html', **params)
        else:
            Users.add_user(in_user, in_pwd)
            self.response.headers['Content-Type'] = 'text/plain'
            self.set_secure_cookie('name', in_user)
            self.redirect('/nerdpress')

#
# Login Handler
#
class LoginHandler(Handler):
    def get(self):
        self.render("login-form.html")
        
    def post(self):
        user = self.request.get('username')
        pwd = self.request.get('password')
        if( Users.login_success(user, pwd)):
            self.response.headers['Content-Type'] = 'text/plain'
            self.set_secure_cookie('name', user)
            self.redirect('/nerdpress')
        else:
            self.render("Login-form.html")

#
# Logout Handler
#
class LogoutHandler(Handler):
    def get(self):
        self.response.headers.add_header('Set-Cookie', 'Name=; Path=/')
        self.redirect('/nerdpress/signup')

#
# Individual page handlers
#
app = webapp2.WSGIApplication([
    ('/', RootHandler),
	('/nerdpress', BlogHandler),
	('/nerdpress/newpost', NewPostHandler),
	('/nerdpress/perm', PermalinkHandler),
    ('/nerdpress/signup', SignupHanlder),
    ('/nerdpress/login', LoginHandler),
    ('/nerdpress/logout', LogoutHandler)
], debug=True)

